import {
  useContext,
  useState,
  useRef,
  useCallback,
  forwardRef,
  ForwardedRef,
  useEffect,
  useImperativeHandle,
} from 'react';
import { Form, Row, Col, Space, Button, Typography } from 'antd';
import { useTranslation } from 'react-i18next';
import { isObject } from 'lodash-es';
import type { FormInstance } from 'antd';
import { ScreenContext } from 'src/context/ScreenContext';
import { IFormProps } from './interface';
import { ScreenTypeEnum } from 'src/interface/theme';
import FormItem from './FormItem';

const rowSpan = 24;

const { Link } = Typography;

const sizeSpanMap = {
  [ScreenTypeEnum.XS]: 24,
  [ScreenTypeEnum.SM]: 24,
  [ScreenTypeEnum.MD]: 12,
  [ScreenTypeEnum.LG]: 8,
  [ScreenTypeEnum.XL]: 6,
  [ScreenTypeEnum.XXL]: 6,
};

function QueryForm(props: IFormProps, ref: ForwardedRef<FormInstance>) {
  const {
    schemas,
    showSubmit = true,
    showCancel = true,
    rowProps = {},
    maxRow = 1,
    loading = false,
    onSubmit,
    ...restFormProps
  } = props;
  const { t } = useTranslation();
  const [factRow, setFactRow] = useState(maxRow);
  const collapsible = useRef<boolean | null>(null);
  const currentSpan = useRef(0);

  const [formInstance] = Form.useForm();
  // 获取处于那种类型
  const { type } = useContext(ScreenContext);

  const toggle = () => {
    if (factRow === Infinity) {
      setFactRow(maxRow);
    } else {
      setFactRow(Infinity);
    }
  };

  const submitHandle = (values: Record<string, any>) => {
    onSubmit && onSubmit(values);
  };

  useEffect(() => {
    if (ref && formInstance) {
      typeof ref === 'function' ? ref(formInstance) : (ref.current = formInstance);
    }
  }, [formInstance, ref]);

  useImperativeHandle(
    ref,
    () => {
      return formInstance;
    },
    [formInstance],
  );

  const renderActions = () => {
    return (
      <div className="flex justify-end">
        {collapsible.current && (
          <Link
            href=""
            className="w-[100%] flex justify-center items-center h-[32px]"
            onClick={(e: any) => {
              e.preventDefault();
              toggle();
            }}>
            {schemas.length > renderSchemaItem().length
              ? t('main.form.fold')
              : t('main.form.unfold')}
          </Link>
        )}
        <Form.Item>
          <Space className="flex justify-end">
            {showSubmit && (
              <Button loading={loading} type="primary" htmlType="submit">
                {t('main.form.search')}
              </Button>
            )}
            {showCancel && <Button htmlType="reset">{t('main.form.reset')}</Button>}
          </Space>
        </Form.Item>
      </div>
    );
  };

  // 动态计算按钮组的Span
  const computedActionColSpan = () => {
    if (currentSpan.current >= maxRow * rowSpan) {
      return rowSpan;
    } else {
      const restSpan = maxRow * rowSpan - currentSpan.current;
      return restSpan > rowSpan ? restSpan - rowSpan * parseInt(`${restSpan / rowSpan}`) : restSpan;
    }
  };
  // 获取schema的colProps 动态计算maxRow 展示多少个

  const renderSchemaItem = useCallback(() => {
    currentSpan.current = 0;
    const filterItemSpan = rowSpan * factRow;
    const renderItems = [] as React.ReactNode[];
    for (const schema of schemas) {
      const { colProps } = schema;
      let span = colProps?.[type];
      span = isObject(span) ? span.span : span ?? sizeSpanMap[type];
      currentSpan.current += Number(span);
      if (currentSpan.current <= filterItemSpan) {
        renderItems.push(<FormItem key={schema.name} {...schema} colProps={{ span: span }} />);
      } else {
        break;
      }
    }
    // 根据 maxRow * rowSpan 获取需要展示的span，再对比
    if (maxRow * rowSpan < currentSpan.current) {
      collapsible.current = true;
    } else {
      collapsible.current = false;
    }

    return renderItems;
  }, [type, schemas, factRow, maxRow]);

  return (
    <Form {...restFormProps} form={formInstance} onFinish={submitHandle}>
      <Row gutter={16} {...rowProps}>
        {renderSchemaItem()}
        <Col span={computedActionColSpan()}>{renderActions()}</Col>
      </Row>
    </Form>
  );
}

export default forwardRef(QueryForm);
export * from './interface';
